package client;

import java.net.InetSocketAddress;
import java.util.ArrayList;

import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoConnector;
import org.apache.mina.common.IoConnectorConfig;
import org.apache.mina.common.IoSession;
import org.apache.mina.transport.socket.nio.SocketConnector;

import protocol.domain.InstantMessage;
import protocol.generic.AbstractProtocolManager;
import protocol.generic.Group;
import protocol.generic.ProtocolException;

/**
 * this class extends AbstractProtocolManager
 * this class is SINGLETON
 * @author wangkaidi
 *
 */
public class YaimProtocolManager extends AbstractProtocolManager
{
	private static YaimProtocolManager manager;//the only instance
	private YaimProtocolManager()
	{
		connector=new SocketConnector();
		((IoConnectorConfig)connector.getDefaultConfig()).setConnectTimeout(10000);			
	}
	
	/**
	 * get the only instance
	 * @return
	 */
	public static synchronized YaimProtocolManager getInstance()
	{
		if(manager==null)
		{
			manager=new YaimProtocolManager();
		}
		return manager;
	}
	
	private IoConnector connector;
	private ConnectFuture future;
	private String username;//the login username ,must be set before connecting;
	private String password;//the login password,must be set before connecting;
	private IoSession session;//the session connected to the chat server
	private ProtocolClientHelper helper=ProtocolClientHelper.getInstance();//the helper instance
	private ArrayList<Group> grouplist;//store buffered Group list
	
	public void setUsername(String username)
	{
		this.username=username;
	}
	
	public String getUsername()
	{
		return username;
	}
	
	public void setPassword(String password)
	{
		this.password=password;
	}
	
	public String getPassword()
	{
		return password;
	}
	/***************************************************
	 * setter and getter method of username and password
	 * *************************************************/
	
	/**
	 * store the session
	 */
	public void setSession(IoSession session)
	{
		this.session=session;
	}
	
	public IoSession getSession()
	{
		return session;
	}
	
	public void setGroups(ArrayList<Group>list)
	{
		this.grouplist=list;
	}
	
	
	@Override
	public void close() 
	{		
		String command=helper.getLogoutRequest();
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
		// TODO close the IoConnector
	}

	@Override
	public void connect() throws ProtocolException 
	{
		try
		{
			future=connector.connect(new InetSocketAddress("localhost", 5222),new YaimClientHandler());		
			future.join();
		}
		catch(Exception e)
		{
			throw new ProtocolException(e.toString());
		}
	}	

	@Override
	public void createGroup(String groupName)
	{		
		//nothing to do
	}

	//@Override
	public void deleteEntry(String groupName, String clientID)
			throws ProtocolException 
	{		
		
	}

	//@Override
	public void deleteGroup(String groupName) throws ProtocolException 
	{		
		String command=helper.getDeleteGroupString(groupName);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
	}

	//@Override
	public void entryCopyToGroup(String clientID, String newGroupName)
			throws ProtocolException 
	{	
		
	}

	//@Override
	public void entryMoveToGroup(String oldGroupName, String clientID,
			String newGroupName) throws ProtocolException 
	{
		
		
	}

	@Override
	public byte[] getAvatar(String clientID) throws ProtocolException 
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ArrayList<Group> getGroups()
	{
		return grouplist;
	}

	@Override
	public void login() throws ProtocolException 
	{		
		if((username==null)||(password==null))
		{
			throw new ProtocolException("must set username and password first");
		}
		if(session==null)
		{
			throw new ProtocolException("internal error: IoSession has not been set");
		}
		String message=helper.getLoginRequest(username, password);
		try
		{
			session.write(message);
		}
		catch(Exception e)
		{
			throw new ProtocolException(e.toString());
		}
	}

	@Override
	public void renameGroup(String oldName, String newName) 
	{	
		String command=helper.getRenameGroupString(oldName, newName);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
	}

	@Override
	public void sendMessage(InstantMessage message) throws ProtocolException 
	{		
		String command=helper.getSendMessageString(message.getDestinationID(), message.getContent());
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{
			throw new ProtocolException(e.toString());
		}
	}

	//@Override
	public void setAvatar(byte[] avatar) throws ProtocolException
	{		
		
	}

	@Override
	public void run()
	{	
		
	}

	@Override
	public void addEntry(String clientID, String alias, String[] groups)
			throws ProtocolException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void copyEntryToGroup(String clientID, String newGroupName)
			throws ProtocolException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void deleteEntry(String clientID) throws ProtocolException {
		// TODO Auto-generated method stub
		String command=helper.getDeleteString(clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
	}

	@Override
	public void deleteEntryFromGroup(String groupName, String clientID)
			throws ProtocolException 
	{
		String command=helper.getDeleteFromGroupString(groupName, clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{
			
		}
	}

	@Override
	public void moveEntryToGroup(String oldGroupName, String clientID,
			String newGroupName) throws ProtocolException 
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void sendSubscriptionRequest(String clientID) 
	{
		String command=helper.getRequestString(clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
	}

	@Override
	public void setAvatar(String fileName) throws ProtocolException 
	{
		
	}

	@Override
	public void sendAuthenticatedReply(String clientID)
	{
		String command=helper.getAgreeString(clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}		
	}

	@Override
	public void sendDeniedReply(String clientID)
	{
		String command=helper.getDenyString(clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}		
	}

	@Override
	public void block(String clientID) {
		// TODO Auto-generated method stub
		String command=helper.getBlockString(clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
	}

	@Override
	public void cancelBlock(String clientID) 
	{
		// TODO Auto-generated method stub
		String command=helper.getUnBlockString(clientID);
		try
		{
			session.write(command);
		}
		catch(Exception e)
		{			
		}
	}
	
}
